﻿package Server.AHMJ.HFSR;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.ArrayUtils;


public class MajHelper {
	static int m_testMjPai[] = { 2, 3, 4, 5, 6, 7, 8, // 2-8 一万-九万
			12, 13, 14, 15, 16, 17, 18, // 12-18一筒-九筒
			22, 23, 24, 25, 26, 27, 28, // 22-28 一条-九条
	};
	static int m_testMjPaiNew[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, // 2-8 一万-九万
			11, 12, 13, 14, 15, 16, 17, 18, 19, // 12-18一筒-九筒
			21, 22, 23, 24, 25, 26, 27, 28, 29 // 22-28 一条-九条
	};

	// 麻将牌paixu
	public static void SortCard(int byHandCard[], int byHandMjCount) {
		for (int i = 0; i < byHandMjCount - 1; i++) {
			for (int j = i; j < byHandMjCount; j++) {
				int x = byHandCard[i];
				int y = byHandCard[j];

				if (x > y) {
					int tempvalue = byHandCard[i];
					byHandCard[i] = byHandCard[j];
					byHandCard[j] = tempvalue;
				}
			}
		}
	}

	/**
	 * 统计258，456,37等的张数
	 * 
	 * @param byHandMj
	 * @param gangInfo
	 *            byActivePai 点炮胡时用来记录胡的那张牌（byHandMj[]中没这个变量）
	 *            gangcishu用来记录杠牌的次数（用于统计全456 全258时的判断）
	 */
	public static int[] countHf(int byHandMj[], int pengPai[], BLOCK_GANGINFO gangInfo[], int byActivePai) {
		int erwuba = 0, siwuliu = 0, sanqi = 0, gangcishu = 0, huPai = 0, pai_hu = 0, zhiPai = 0;
		for (int i = 0; i < pengPai.length; i++) {
			if (pengPai[i] != 0) {
				if (pengPai[i] % 10 == 5) {
					erwuba += 3;
					siwuliu += 3;
				}
				if (pengPai[i] % 10 == 2 || pengPai[i] % 10 == 8) {
					erwuba += 3;
				}
				if (pengPai[i] % 10 == 4 || pengPai[i] % 10 == 6) {
					siwuliu += 3;
				}
				if (pengPai[i] % 10 == 3 || pengPai[i] % 10 == 7) {
					sanqi += 3;
				}
			}
		}
		if (byActivePai != 255) {
			huPai = byActivePai % 10;
		}
		if (huPai == 5) {
			erwuba++;
			siwuliu++;
		}
		if (huPai == 2 || huPai == 8) {
			erwuba++;
		}
		if (huPai == 4 || huPai == 6) {
			siwuliu++;
		}
		if (huPai == 3 || huPai == 7) {
			sanqi++;
		}
		for (int i = 0; i < byHandMj.length; i++) {
			int pai = byHandMj[i];
			if (pai != Constants.INVALID_CARD) {
				pai = pai % 10;
				if (pai == 5) {
					erwuba++;
					siwuliu++;
				}
				if (pai == 2 || pai == 8) {
					erwuba++;
				}
				if (pai == 4 || pai == 6) {
					siwuliu++;
				}
				if (pai == 3 || pai == 7) {
					sanqi++;
				}
			}
		}
		for (int i = 0; i < gangInfo.length; i++) {
			int pai = gangInfo[i].first;
			if (pai != Constants.INVALID_CARD) {
				gangcishu++;
				pai = pai % 10;
				if (pai == 5) {
					erwuba += 4;
					siwuliu += 4;
				}
				if (pai == 2 || pai == 8) {
					erwuba += 4;
				}
				if (pai == 4 || pai == 6) {
					siwuliu += 4;
				}
				if (pai == 3 || pai == 7) {
					sanqi += 4;
				}
			}
		}
		// 统计支的分数
		int wanCount = 0, tongCount = 0, tiaoCount = 0;
		for (int i = 0; i < byHandMj.length; i++) {
			int pai = byHandMj[i];
			if (1 <= pai && pai <= 9) {
				wanCount++;
			}
			if (11 <= pai && pai <= 19) {
				tongCount++;
			}
			if (21 <= pai && pai <= 29) {
				tiaoCount++;
			}
		}
		for (int i = 0; i < gangInfo.length; i++) {
			int pai = gangInfo[i].first;
			if (1 <= pai && pai <= 9) {
				wanCount += 4;
			}
			if (11 <= pai && pai <= 19) {
				tongCount += 4;
			}
			if (21 <= pai && pai <= 29) {
				tiaoCount += 4;
			}
		}
		for (int i = 0; i < pengPai.length; i++) {
			if (pengPai[i] != 0) {
				if (1 <= pengPai[i] && pengPai[i] <= 9) {
					wanCount += 3;
				}
				if (11 <= pengPai[i] && pengPai[i] <= 19) {
					tongCount += 3;
				}
				if (21 <= pengPai[i] && pengPai[i] <= 29) {
					tiaoCount += 3;
				}
			}
		}
		if (byActivePai != 255) {
			pai_hu = byActivePai;
		}
		if (1 <= pai_hu && pai_hu <= 9) {
			wanCount += 1;
		}
		if (11 <= pai_hu && pai_hu <= 19) {
			tongCount += 1;
		}
		if (21 <= pai_hu && pai_hu <= 29) {
			tiaoCount += 1;
		}
		if (wanCount > 8) {
			zhiPai = wanCount;
		}
		if (tongCount > 8) {
			zhiPai = tongCount;
		}
		if (tiaoCount > 8) {
			zhiPai = tiaoCount;
		}
		// 统计同的分数
		int tong1 = 0, tong2 = 0, tong3 = 0, tong4 = 0, tong5 = 0, tong6 = 0, tong7 = 0, tong8 = 0, tong9 = 0;
		for (int i = 0; i < byHandMj.length; i++) {
			if (byHandMj[i] != 255) {
				switch (byHandMj[i] % 10) {
				case 1: {
					tong1++;
					break;
				}
				case 2: {
					tong2++;
					break;
				}
				case 3: {
					tong3++;
					break;
				}
				case 4: {
					tong4++;
					break;
				}
				case 5: {
					tong5++;
					break;
				}
				case 6: {
					tong6++;
					break;
				}
				case 7: {
					tong7++;
					break;
				}
				case 8: {
					tong8++;
					break;
				}
				case 9: {
					tong9++;
					break;
				}
				}
			}
		}
		if (byActivePai != 255) {
			switch (byActivePai % 10) {
			case 1: {
				tong1++;
				break;
			}
			case 2: {
				tong2++;
				break;
			}
			case 3: {
				tong3++;
				break;
			}
			case 4: {
				tong4++;
				break;
			}
			case 5: {
				tong5++;
				break;
			}
			case 6: {
				tong6++;
				break;
			}
			case 7: {
				tong7++;
				break;
			}
			case 8: {
				tong8++;
				break;
			}
			case 9: {
				tong9++;
				break;
			}
			}
		}
		for (int i = 0; i < gangInfo.length; i++) {
			int gangPai = gangInfo[i].first;
			if (gangPai != 255) {
				switch (gangPai % 10) {
				case 1: {
					tong1 += 4;
				}
					break;
				case 2: {
					tong2 += 4;
				}
					break;
				case 3: {
					tong3 += 4;
				}
					break;
				case 4: {
					tong4 += 4;
				}
					break;
				case 5: {
					tong5 += 4;
				}
					break;
				case 6: {
					tong6 += 4;
				}
					break;
				case 7: {
					tong7 += 4;
				}
					break;
				case 8: {
					tong8 += 4;
				}
					break;
				case 9: {
					tong9 += 4;
				}
					break;
				}
			}
		}
		for(int i = 0; i<pengPai.length; i++){
			if(pengPai[i] != 0){
				if(pengPai[i]%10 == 1){
					tong1 += 3;
				}
				if(pengPai[i]%10 == 2){
					tong2 += 3;
				}
				if(pengPai[i]%10 == 3){
					tong3 += 3;
				}
				if(pengPai[i]%10 == 4){
					tong4 += 3;
				}
				if(pengPai[i]%10 == 5){
					tong5 += 3;
				}
				if(pengPai[i]%10 == 6){
					tong6 += 3;
				}
				if(pengPai[i]%10 == 7){
					tong7 += 3;
				}
				if(pengPai[i]%10 == 8){
					tong8 += 3;
				}
				if(pengPai[i]%10 == 9){
					tong9 += 3;
				}
			}
		}
		return new int[] { erwuba, siwuliu, sanqi, gangcishu, zhiPai, tong1, tong2, tong3, tong4, tong5, tong6, tong7,
				tong8, tong9 };
	}

	// 统计坎、四活、对子
	public static int[] countKan(int tempMj[], int pengPai[]) {

		Map<Integer, Integer> paiCount = new HashMap<>();
		Integer countNum = 0;
		for (int i = 0; i < tempMj.length; i++) {
			System.err.print(tempMj[i]+" ");
			int pai = tempMj[i];
			if (pai != 255) {
				countNum = paiCount.get(pai);
			}
			if (countNum == null) {
				paiCount.put(pai, 1);
			} else {
				paiCount.put(pai, countNum + 1);
			}
		}
		// Integer activePai = byActivePai;
		// if(activePai != 255){
		// countNum = paiCount.get(activePai);
		// }
		// if(countNum==null){
		// paiCount.put(activePai, 1);
		// }else{
		// paiCount.put(activePai, countNum+1);
		// }
		int duiCount = 0;
		int kanCount = 0;
		int siHuoCount = 0;
		for (Integer pai : paiCount.keySet()) {
			Integer count = paiCount.get(pai);
			if (count == 2) {
				duiCount++;
			}
			if (count == 3) {
				kanCount++;
			}
			if (count == 4) {
				siHuoCount++;
				System.err.println("四活个数............."+siHuoCount);
			}
		}
		for (int i = 0; i < pengPai.length; i++) {
			for (int j = 0; j < tempMj.length; j++) {
				if (pengPai[i] != 0 && pengPai[i] == tempMj[j]) {
					System.err.println("1333333333333333"+pengPai[i]);
					siHuoCount++;
				}
			}
		}
		return new int[] { kanCount, siHuoCount, duiCount };
	}

	public static boolean IsHu(int byHandMj[], int pengPai[], BLOCK_GANGINFO gangInfo[], int byMj) {
		return IsHu(byHandMj, pengPai, gangInfo, byMj, new HU(), new HU(), null);
	}

	public static int GetRelativeSeat(int bySeatID, int byLastOutUser) {
		int currindex = bySeatID;
		int outindex = byLastOutUser;
		if (currindex == 3 && outindex == 0)
			outindex = 4;
		else if (currindex == 0 && outindex == 3)
			currindex = 4;
		if (currindex - outindex == 1)
			return 0;
		else if (outindex - currindex == 1)
			return 2;
		else
			return 1;
	}

	// 统计胡牌的人 杠的
	public static int gangCount(BLOCK_GANGINFO gangInfo[]) {
		int gangCount = 0;
		for (int i = 0; i < 4; i++) {
			if (gangInfo[i].first != 255) {
				gangCount++;
			}
		}
		return gangCount;
	}

	public static boolean IsZhiTing(int byHandMj[], int pengPai[], BLOCK_GANGINFO gangInfo[]) {
		int wanCount = 0, tongCount = 0, tiaoCount = 0, countGang = 0;
		for (int i = 0; i < byHandMj.length; i++) {
			int pai = byHandMj[i];
			if (1 <= pai && pai <= 9) {
				wanCount++;
			}
			if (11 <= pai && pai <= 19) {
				tongCount++;
			}
			if (21 <= pai && pai <= 29) {
				tiaoCount++;
			}
		}
		for (int i = 0; i < gangInfo.length; i++) {
			int pai = gangInfo[i].first;
			if (1 <= pai && pai <= 9) {
				wanCount += 3;
			}
			if (11 <= pai && pai <= 19) {
				tongCount += 3;
			}
			if (21 <= pai && pai <= 29) {
				tiaoCount += 3;
			}
		}
		for (int i = 0; i < pengPai.length; i++) {
			if (1 <= pengPai[i] && pengPai[i] <= 9) {
				wanCount += 3;
			}
			if (11 <= pengPai[i] && pengPai[i] <= 19) {
				tongCount += 3;
			}
			if (21 <= pengPai[i] && pengPai[i] <= 29) {
				tiaoCount += 3;
			}
		}
		// return ( wanCount>=7 || tongCount>=7 || tiaoCount>=7 );
		for (int i = 0; i < gangInfo.length; i++) {
			if (gangInfo[i].first != 255) {
				countGang++;
			}
			if (1 <= gangInfo[i].first && gangInfo[i].first <= 9) {
				gangInfo[i].style = -1;// 万
			}
			if (11 <= gangInfo[i].first && gangInfo[i].first <= 19) {
				gangInfo[i].style = -2;// 筒
			}
			if (21 <= gangInfo[i].first && gangInfo[i].first <= 29) {
				gangInfo[i].style = -3;// 条
			}
		}
		if (countGang <= 1) {
			return (wanCount >= 7 || tongCount >= 7 || tiaoCount >= 7);
		} else if (countGang == 2) {
			if (gangInfo[0].style == gangInfo[0].style) {
				return true;
			} else {
				return (wanCount >= 7 || tongCount >= 7 || tiaoCount >= 7);
			}
		} else if (countGang == 3) {
			if (gangInfo[0].style == gangInfo[1].style || gangInfo[0].style == gangInfo[2].style
					|| gangInfo[1] == gangInfo[2]) {
				return true;
			} else {
				return (wanCount >= 7 || tongCount >= 7 || tiaoCount >= 7);
			}
		}
		return true;
	}

	//////////////////////////////////////////////////////////////////////////
	public static boolean IsHu(int byHandMj[], int pengPai[], BLOCK_GANGINFO gangInfo[], int byMj, HU hu, HU tempHu,
			int byHuaPai[]) {
		if (!IsZhiTing(byHandMj, pengPai, gangInfo)) {
			return false;
		}
		// 排序牌面
		int OriginalMj[] = new int[Constants.HAND_MJ_MAX];
		Constants.memcpy(OriginalMj, byHandMj, Constants.HAND_MJ_MAX);
		if (byMj != Constants.INVALID_CARD) {
			OriginalMj[Constants.HAND_MJ_MAX - 1] = byMj;
		}
		SortCard(OriginalMj, (int) Constants.HAND_MJ_MAX);
		// /*
		// * 霍邱麻将这里不一样，不再判断
		if (IsPaiXinQiDuiZi(OriginalMj) > 0) {
			return true;
		}
		// 将牌位在整数块( 0, 3, 6, 9, 12, 15 )处
		// 设置变量
		MJ_BLOCK block1;
		for (int i = 0; i < Constants.HAND_MJ_MAX - 1; i++) {
			int tempMj[] = new int[Constants.HAND_MJ_MAX];
			Constants.memcpy(tempMj, OriginalMj, Constants.HAND_MJ_MAX);
			if (IsJiang(tempMj[i], tempMj[i + 1])) {
				// 胡牌结构处理
				CleanHu(tempHu);
				CopyHu(tempHu, hu);
				tempHu.jiangMj = tempMj[i];
				tempMj[i] = Constants.INVALID_CARD;
				tempMj[i + 1] = Constants.INVALID_CARD;
				SortCard(tempMj, (int) Constants.HAND_MJ_MAX);
				// 单钓
				if (tempHu.block[(Constants.HAND_MJ_MAX - 2) / 3 - 1].style != Constants.BLOCK_NULL) {
					return true;
				}
				for (int j = 0; j < Constants.HAND_MJ_MAX - 2; j += 3) {
					block1 = CheckBlock(tempMj[j], tempMj[j + 1], tempMj[j + 2]);
					if (block1.style != Constants.BLOCK_NULL) {
						AddBlock(tempHu, block1);
					} else {
						// 有相嵌的两个BLOCK结构,或三个BLOCK结构
						if (j + 5 <= Constants.HAND_MJ_MAX - 1) {
							MJ_BLOCK block2;
							// 两种情况 223344 或 233334 或 233444556 或 233344455 或
							// 334445556
							// 情况1 223344 233445
							block1 = CheckBlock(tempMj[j], tempMj[j + 2], tempMj[j + 4]);
							block2 = CheckBlock(tempMj[j + 1], tempMj[j + 3], tempMj[j + 5]);
							if (block1.style != Constants.BLOCK_NULL && block2.style != Constants.BLOCK_NULL) {
								AddBlock(tempHu, block1);
								AddBlock(tempHu, block2);
								j += 3;
							}
							// 情况2 233334
							else {
								block1 = CheckBlock(tempMj[j], tempMj[j + 1], tempMj[j + 5]);
								block2 = CheckBlock(tempMj[j + 2], tempMj[j + 3], tempMj[j + 4]);
								if (block1.style != Constants.BLOCK_NULL && block2.style != Constants.BLOCK_NULL) {
									AddBlock(tempHu, block1);
									AddBlock(tempHu, block2);
									j += 3;
								}
								// 情况3 233444556
								else {
									if (j + 8 <= Constants.HAND_MJ_MAX - 1) {
										MJ_BLOCK block3 = new MJ_BLOCK();
										block1 = CheckBlock(tempMj[j], tempMj[j + 1], tempMj[j + 3]);
										block2 = CheckBlock(tempMj[j + 2], tempMj[j + 4], tempMj[j + 6]);
										block3 = CheckBlock(tempMj[j + 5], tempMj[j + 7], tempMj[j + 8]);
										if (block1.style != Constants.BLOCK_NULL && block2.style != Constants.BLOCK_NULL
												&& block3.style != Constants.BLOCK_NULL) {
											AddBlock(tempHu, block1);
											AddBlock(tempHu, block2);
											AddBlock(tempHu, block3);
											j += 6;
										}
										// 情况3 334445556
										else {
											MJ_BLOCK block31 = new MJ_BLOCK();
											block1 = CheckBlock(tempMj[j], tempMj[j + 1], tempMj[j + 4]);
											block2 = CheckBlock(tempMj[j + 2], tempMj[j + 5], tempMj[j + 7]);
											block31 = CheckBlock(tempMj[j + 3], tempMj[j + 6], tempMj[j + 8]);
											if (block1.style != Constants.BLOCK_NULL
													&& block2.style != Constants.BLOCK_NULL
													&& block31.style != Constants.BLOCK_NULL) {
												AddBlock(tempHu, block1);
												AddBlock(tempHu, block2);
												AddBlock(tempHu, block31);
												j += 6;
											} else {
												block1 = CheckBlock(tempMj[j], tempMj[j + 2], tempMj[j + 5]);
												block2 = CheckBlock(tempMj[j + 1], tempMj[j + 3], tempMj[j + 6]);
												block31 = CheckBlock(tempMj[j + 4], tempMj[j + 7], tempMj[j + 8]);
												if (block1.style != Constants.BLOCK_NULL
														&& block2.style != Constants.BLOCK_NULL
														&& block31.style != Constants.BLOCK_NULL) {
													AddBlock(tempHu, block1);
													AddBlock(tempHu, block2);
													AddBlock(tempHu, block31);
													j += 6;
												}
											}
										}
									}
								}
							}

						} else {
							break;
						}
					}
					if (tempHu.block[(Constants.HAND_MJ_MAX - 2) / 3 - 1].style != Constants.BLOCK_NULL) {
						return true;
					}
				}
			}
		}

		return false;
	}

	public static boolean IsTing(int byHandMj[], int pengPai[], BLOCK_GANGINFO gangInfo[], int byMj, HU hu,
			int intstMj[], int intstMjCount, int byHuaPai[]) {
		if (!IsZhiTing(byHandMj, pengPai, gangInfo)) {
			return false;
		}
		int byHandMjCount = 0;
		for (int byIndex = 0; byIndex < Constants.HAND_MJ_MAX; byIndex++) {
			if (MajHelper.IsWTSZ(byHandMj[byIndex])) {
				byHandMjCount++;
			}
		}
		for (int byIndex = 0; byIndex < Constants.HAND_MJ_MAX; byIndex++) {
			int intmpMj[] = new int[Constants.HAND_MJ_MAX];
			Constants.memcpy(intmpMj, byHandMj, Constants.HAND_MJ_MAX);
			if (((byHandMjCount
					% 3) == 2) /* && (byMj == Constants.INVALID_CARD) */) {
				intmpMj[byIndex] = Constants.INVALID_CARD;
			}
			if (byIndex != Constants.HAND_MJ_MAX - 1) {
				intmpMj[Constants.HAND_MJ_MAX - 1] = byMj;
			}

			SortCard(intmpMj, (int) Constants.HAND_MJ_MAX);
			for (int i = 0; i < intstMjCount; i++) {
				int intstMjValue = intstMj[i];
				HU tempHu = new HU();
				CleanHu(tempHu);
				if (IsHu(intmpMj, pengPai, gangInfo, intstMjValue, hu, tempHu, byHuaPai)) {
					return true;
				}
			}
		}
		return false;
	}

	public static int GetTingPai(int byHandMj[], int pengPai[], BLOCK_GANGINFO gangInfo[], HU hu, int byHuaPai[],
			int byResultTingMj[],String dai19) {
		int byTingPaiCount = 0;
		int intmpMj[] = new int[Constants.HAND_MJ_MAX];
		Constants.memcpy(intmpMj, byHandMj, Constants.HAND_MJ_MAX);
		intmpMj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;

		SortCard(intmpMj, Constants.HAND_MJ_MAX);
		if(dai19 != "DAI19"){
			for (int i = 0; i < 21; i++) {
				int byMj = m_testMjPai[i];
				HU tempHu = new HU();
				CleanHu(tempHu);
				if (IsHu(intmpMj, pengPai, gangInfo, byMj, hu, tempHu, byHuaPai)) {
					byResultTingMj[byTingPaiCount++] = byMj;
				}
			}
		}else{
			for (int i = 0; i < 27; i++) {
				int byMj = m_testMjPaiNew[i];
				HU tempHu = new HU();
				CleanHu(tempHu);
				if (IsHu(intmpMj, pengPai, gangInfo, byMj, hu, tempHu, byHuaPai)) {
					byResultTingMj[byTingPaiCount++] = byMj;
				}
			}
		}

		return byTingPaiCount;
	}

	public static int GetTingPaiNew(int byHandMj[], int pengPai[], BLOCK_GANGINFO gangInfo[], HU hu, int byHuaPai[],
			int byResultTingMj[]) {
		int byTingPaiCount = 0;
		int intmpMj[] = new int[Constants.HAND_MJ_MAX];
		Constants.memcpy(intmpMj, byHandMj, Constants.HAND_MJ_MAX);
		intmpMj[Constants.HAND_MJ_MAX - 1] = Constants.INVALID_CARD;

		SortCard(intmpMj, Constants.HAND_MJ_MAX);
		for (int i = 0; i < 27; i++) {
			int byMj = m_testMjPaiNew[i];
			HU tempHu = new HU();
			CleanHu(tempHu);
			if (IsHu(intmpMj, pengPai, gangInfo, byMj, hu, tempHu, byHuaPai)) {
				byResultTingMj[byTingPaiCount++] = byMj;
			}
		}

		return byTingPaiCount;
	}

	// 自摸明杠 返回,
	public static MJ_GANGINFO IsZMGang(int byHandMj[], HU hu, int jPos1, int jPos2, int jPos3) {
		MJ_GANGINFO gangInfo = new MJ_GANGINFO();
		gangInfo.GangStyle = 0;
		gangInfo.GangMj = Constants.INVALID_CARD;
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			if (hu.block[i].style == Constants.BLOCK_NULL)
				break;
			else if (hu.block[i].style != Constants.BLOCK_PENG)
				continue;
			else {
				// 跳过多个补杠
				if (hu.block[i].first == jPos1 || hu.block[i].first == jPos2 || hu.block[i].first == jPos3)
					continue;
				for (int j = 0; j < Constants.HAND_MJ_MAX; j++) {
					// if( byHandMj[j]==jPos1 || byHandMj[j]==jPos2 )
					// continue;
					if (byHandMj[j] == hu.block[i].first) {
						gangInfo.GangStyle = 2; // 自摸明杠
						gangInfo.GangMj = byHandMj[j]; // 明杠胡牌块位
						return gangInfo;
					}
				}
			}
		}
		return gangInfo;
	}

	public static int GetPaiCount(int byHandMj[]) {
		int cnt = 0;
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			if (byHandMj[i] != Constants.INVALID_CARD) {
				cnt++;
			}
		}
		return cnt;
	}

	public static int GetPaiCount(int byHandMj[], int byMj) {
		int cnt = 0;
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			if (byHandMj[i] == byMj) {
				cnt++;
			}
		}
		return cnt;
	}

	public static boolean TestBit(int var, int bit) {
		return ((var) & (1 << (bit))) != 0;
	}

	// 加入块到胡牌结构
	public static int AddBlock(HU hu, PTR_MJ_BLOCK block) {
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			if (hu.block[i].style == Constants.BLOCK_NULL) {
				hu.block[i].first = block.first;
				hu.block[i].style = block.style;
				hu.block[i].origValue = block.origValue;
				return i;
			}
		}
		return 255;
	}

	public static int AddBlock(HU hu, BLOCK block) {
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			if (hu.block[i].style == Constants.BLOCK_NULL) {
				hu.block[i].first = block.first;
				hu.block[i].style = block.style;
				hu.block[i].origValue = block.origValue;
				return i;
			}
		}
		return 255;
	}

	public static int AddBlock(HU hu, MJ_BLOCK block) {
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			if (hu.block[i].style == Constants.BLOCK_NULL) {
				hu.block[i].first = block.first;
				hu.block[i].style = block.style;
				hu.block[i].origValue = block.origValue;
				if (block.OutUserGang != -1) {
					hu.block[i].OutUserGang = block.OutUserGang;
				}
				return i;
			}
		}
		return 255;
	}

	// 类型判断
	public static MJ_BLOCK CheckBlock(int byMj1, int byMj2, int byMj3) {
		MJ_BLOCK block = new MJ_BLOCK();
		block.first = Constants.INVALID_CARD;
		block.style = Constants.BLOCK_NULL;

		if (byMj1 == Constants.INVALID_CARD || byMj2 == Constants.INVALID_CARD || byMj3 == Constants.INVALID_CARD) {
			return block;
		}
		if (IsTongHuaSe(byMj1, byMj2, byMj3) == false) {
			return block;
		}
		// 如果byMj1, byMj2, byMj3不是顺序结构,排序
		int i, tag, temp;
		for (i = 0, tag = 1; tag == 1 && i < 3; i++) {
			tag = 0;
			if (byMj1 > byMj2) {
				temp = byMj1;
				byMj1 = byMj2;
				byMj2 = temp;
				tag = 1;
			}
			if (byMj2 > byMj3) {
				temp = byMj2;
				byMj2 = byMj3;
				byMj3 = temp;
				tag = 1;
			}
		}

		// 碰形结构
		if (byMj1 == byMj2 && byMj2 == byMj3) {
			block.first = byMj1;
			block.style = Constants.BLOCK_KE;
			return block;
		}

		// 顺形结构
		if (IsWST(byMj3) && IsWST(byMj1)) // 不为字, 花
		{
			if (byMj3 == byMj2 + 1 && byMj2 == byMj1 + 1) {
				block.first = byMj1;
				block.style = Constants.BLOCK_SUN;
				return block;
			}
		}
		return block;
	}

	// 是否可以做将牌
	public static boolean IsJiang(int byMj1, int byMj2) {
		if (byMj1 == byMj2 && MajHelper.IsWTSZ(byMj1)) {
			return true;
		}
		return false;
	}

	public static boolean IsTongHuaSe(int byMj1, int byMj21, int byMj31) {
		int byMj2 = byMj21;
		int byMj3 = byMj31;
		if (IsWan(byMj1) && IsWan(byMj2) && IsWan(byMj3)) {
			return true;
		}
		if (IsTong(byMj1) && IsTong(byMj2) && IsTong(byMj3)) {
			return true;
		}
		if (IsSuo(byMj1) && IsSuo(byMj2) && IsSuo(byMj3)) {
			return true;
		}

		if ((byMj1 == byMj2) && (byMj2 == byMj3) && MajHelper.IsWTSZ(byMj1)) {
			return true;
		}
		return false;
	}

	public static boolean IsTongHuaSe(int byMj1, int byMj2) {
		if (IsWan(byMj1) && IsWan(byMj2)) {
			return true;
		}
		if (IsTong(byMj1) && IsTong(byMj2)) {
			return true;
		}
		if (IsSuo(byMj1) && IsSuo(byMj2)) {
			return true;
		}

		if (byMj1 == byMj2 && MajHelper.IsWTSZ(byMj1)) {
			return true;
		}
		return false;
	}

	public static boolean IsWTSZ(int byMj) {
		if (byMj >= 1 && byMj <= 9)// 二万~八万
		{
			return true;
		}
		if (byMj >= 11 && byMj <= 19)// 二筒~八筒
		{
			return true;
		}
		if (byMj >= 21 && byMj <= 29)// 二条~八条
										// -----------------------------------------------
		{
			return true;
		}
		if (byMj >= 31 && byMj <= 37)// 东南西北中发白
		{
			return true;
		}
		if (byMj >= 41 && byMj <= 48)// 春夏秋冬梅兰竹菊
		{
			return true;
		}
		return false;
	}

	// 是否是万索筒
	public static boolean IsWST(int byMj1) {
		if (IsWan(byMj1)) {
			return true;
		}
		if (IsTong(byMj1)) {
			return true;
		}
		if (IsSuo(byMj1)) {
			return true;
		}
		return false;
	}

	public static boolean IsWan(int byMj1) {
		if (byMj1 >= 1 && byMj1 <= 9) {
			return true;
		}
		return false;
	}

	public static boolean IsTong(int byMj1) {
		if (byMj1 >= 11 && byMj1 <= 19) {
			return true;
		}
		return false;
	}

	public static boolean IsSuo(int byMj1) {
		if (byMj1 >= 21 && byMj1 <= 29) {
			return true;
		}
		return false;
	}

	// 是否是风牌
	public static boolean IsZi(int byMj1) {
		if (byMj1 >= 31 && byMj1 <= 37) {
			return true;
		}
		return false;
	}

	// 是否是风牌
	public static boolean IsFeng(int byMj1) {
		if (byMj1 >= 31 && byMj1 <= 37) {
			return true;
		}
		return false;
	}

	// 是否是三元
	public static boolean IsSanYuan(int byMj1) {
		if (byMj1 >= 35 && byMj1 <= 37) {
			return true;
		}
		return false;
	}

	// 是否是花
	public static boolean IsHua(int byMj1) {
		if (byMj1 >= 41 && byMj1 <= 48) {
			return true;
		}
		return false;
	}

	public static int GameUserNum = 3;

	public static int GetNextUser(int bySeatID) {
		return (bySeatID + 1) % GameUserNum;
	}

	// 是否是花牌
	public static boolean IsHuaPai(int byPai) {
		if (byPai >= 41 && byPai <= 48) {
			return true;
		}
		return false;
	}

	// 是否可以吃牌

	// 是否可以碰牌
	public static boolean IsPeng(int byHandMj[], int byMj) {
		for (int i = 0; i < Constants.HAND_MJ_MAX - 1 - 1; i++) {
			if (byHandMj[i] == byMj && byHandMj[i + 1] == byMj && IsTongHuaSe(byMj, byHandMj[i], byHandMj[i + 1])) {
				return true;
			}
		}
		return false;
	}

	// 是否明杠
	public static MJ_GANGINFO IsGang(int byHandMj[], int byMj) {
		MJ_GANGINFO gangInfo = new MJ_GANGINFO();
		gangInfo.GangStyle = 0;
		gangInfo.GangMj = 0;
		// 明杠手上不会有第十四张牌
		for (int i = 0; i < Constants.HAND_MJ_MAX - 3; i++) {
			if (byHandMj[i] == byMj && byHandMj[i + 1] == byMj && byHandMj[i + 2] == byMj) {
				gangInfo.GangMj = byHandMj[i];
				gangInfo.GangStyle = 1;
			}
		}
		return gangInfo;
	}

	// 自摸明杠-补杠
	public static void ZMGang(int byMjs[], HU hu, int GangMj) {
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			if (hu.block[i].first == GangMj) {
				hu.block[i].style = Constants.BLOCK_BU_GANG;
				break;// 右移一格
			}
		}
		for (int j = 0; j < Constants.HAND_MJ_MAX; j++) {
			if (byMjs[j] == GangMj) {
				byMjs[j] = Constants.INVALID_CARD;
				break;
			}
		}
	}

	public static MJ_GANGINFO IsZMGang(int byHandMj[], HU hu) {
		return IsZMGang(byHandMj, hu, 255, 255, 255);
	}

	public static boolean IsCanGangNoBaoZi(int byHandMj[], HU hu, int byMj) {
		if (IsShunQiGang(byHandMj, hu, byMj)) {
			return true;
		}
		if (IsAnGang(byHandMj).GangStyle != 0) {
			return true;
		}
		return false;
	}

	public static int getCardNumber(int byHandMj[], int mj) {
		int num = 0;
		for (int i = 0; i < byHandMj.length; i++) {
			if (byHandMj[i] == mj)
				num++;
		}
		return num;
	}

	// 自摸明杠 返回,
	public static boolean IsShunQiGang(int byHandMj[], HU hu, int byMj) {
		MJ_GANGINFO gangInfo = new MJ_GANGINFO();
		gangInfo.GangStyle = 0;
		gangInfo.GangMj = Constants.INVALID_CARD;
		return false;
	}

	// 自摸明杠 返回,

	public static MJ_GANGINFO IsAnGang(int byHandMj[]) {
		return IsAnGang(byHandMj, 255, 255, 255);
	}

	public static MJ_GANGINFO IsAnGang(int byHandMj[], int jPos1) {
		return IsAnGang(byHandMj, jPos1, 255, 255);
	}

	public static MJ_GANGINFO IsAnGang(int byHandMj[], int jPos1, int jPos2) {
		return IsAnGang(byHandMj, jPos1, jPos2, 255);
	}

	// 是否暗杠
	public static MJ_GANGINFO IsAnGang(int byHandMj[], int jPos1, int jPos2, int jPos3) {
		MJ_GANGINFO gangInfo = new MJ_GANGINFO();
		gangInfo.GangStyle = 0;
		gangInfo.GangMj = Constants.INVALID_CARD;
		for (int i = 0; i < Constants.HAND_MJ_MAX - 3; i++) {
			// 跳过
			if (byHandMj[i] == jPos1 || byHandMj[i] == jPos2 || byHandMj[i] == jPos3)
				continue;
			if (byHandMj[i] == byHandMj[i + 1] && byHandMj[i] == byHandMj[i + 2]) {
				// 手上有杠牌
				if (byHandMj[i] == byHandMj[i + 3]) {
					gangInfo.GangStyle = 4;
					gangInfo.GangMj = byHandMj[i];
				}
				// 刚摸到杠牌
				else if (byHandMj[i] == byHandMj[Constants.HAND_MJ_MAX - 1]) {
					gangInfo.GangStyle = 4;
					gangInfo.GangMj = byHandMj[i];
				}
			}
		}
		MajPaiQiang m_MajPaiQiang = new MajPaiQiang();
		SUBCMD_S_YuPai cmd1 = new SUBCMD_S_YuPai();
		cmd1.byYuPai = m_MajPaiQiang.GetYuPaiCount();
		if (cmd1.byYuPai <= 4) {
			gangInfo.GangStyle = 0;
		}
		return gangInfo;
	}

	// 清除胡牌数据
	public static void CleanHu(HU hu) {
		hu.jiangMj = Constants.INVALID_CARD;
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			if (hu.block[i] == null) {
				hu.block[i] = new BLOCK();
			}
			hu.block[i].first = Constants.INVALID_CARD;
			hu.block[i].style = Constants.BLOCK_NULL;
		}
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			hu.sanMj[i] = Constants.INVALID_CARD;
		}
	}

	// 拷贝胡牌数据
	public static void CopyHu(HU destHu, HU srcHu) {
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			destHu.block[i].first = srcHu.block[i].first;
			destHu.block[i].style = srcHu.block[i].style;
		}
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			destHu.sanMj[i] = srcHu.sanMj[i];
		}
	}

	public static void HuToHandMj(int byMjs[], HU srcHu) {
		int j = 0;
		for (int i = 0; i < (Constants.HAND_MJ_MAX - 2) / 3; i++) {
			switch (srcHu.block[i].style) {
			case Constants.BLOCK_NULL: {

			}
				break;
			case Constants.BLOCK_SUN: // 顺序结构
			{
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = (srcHu.block[i].first + 1);
				byMjs[j++] = (srcHu.block[i].first + 2);
			}
				break;
			case Constants.BLOCK_KE: // 刻子结构,3个相同,非碰
			{
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
			}
				break;
			case Constants.BLOCK_GANG: // 杠子结构,4个相同
			{
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
			}
				break;
			case Constants.BLOCK_BU_GANG: {
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
			}
				break;
			case Constants.BLOCK_AN_GANG: // 暗杠
			{
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
				byMjs[j++] = srcHu.block[i].first;
			}
				break;
			}
		}
		int srcHujiangMj = srcHu.jiangMj;
		byMjs[j++] = srcHujiangMj;
		byMjs[j++] = srcHujiangMj;
		for (int a = 0; a < byMjs.length; a++) {
			System.out.print(byMjs[a] + " ");
		}
		System.out.println();
	}

	public static int DeletePai(int byHandMj[], int byMj1) {
		return DeletePai(byHandMj, byMj1, 255, 255);
	}

	public static int DeletePai(int byHandMj[], int byMj1, int byMj2) {
		return DeletePai(byHandMj, byMj1, byMj2, 255);
	}

	public static int DeletePai(int byHandMj[], int byMj1, int byMj2, int byMj3) {
		int cnt = 0;
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			if (byHandMj[i] == byMj1 && byMj1 != Constants.INVALID_CARD) {
				byHandMj[i] = Constants.INVALID_CARD;
				byMj1 = Constants.INVALID_CARD;
				cnt++;
			}
			if (byHandMj[i] == byMj2 && byMj2 != Constants.INVALID_CARD) {
				byHandMj[i] = Constants.INVALID_CARD;
				byMj2 = Constants.INVALID_CARD;
				cnt++;
			}
			if (byHandMj[i] == byMj3 && byMj3 != Constants.INVALID_CARD) {
				byHandMj[i] = Constants.INVALID_CARD;
				byMj3 = Constants.INVALID_CARD;
				cnt++;
			}
		}
		SortCard(byHandMj, Constants.HAND_MJ_MAX);
		return cnt;
	}

	// 分析胡牌类型,返回番数
	public static long CheckGDHu(HU hu, int byFengWei, int byQuanWei, char strFang) {
		return 0;
	}

	public static BLOCK Peng(int byMjs[], int byMj) {
		MJ_BLOCK block = new MJ_BLOCK();
		for (int i = 0; i < Constants.HAND_MJ_MAX - 1; i++) {
			if (byMjs[i] == byMj && byMjs[i + 1] == byMj) {// 普通碰
				byMjs[i] = Constants.INVALID_CARD;
				byMjs[i + 1] = Constants.INVALID_CARD;
				// 右移3格
				break;
			}
		}
		block.first = byMj;
		block.style = Constants.BLOCK_PENG;
		return block;
	}

	// 杠操作
	public static BLOCK MGang(int byMjs[], int byMj, int CurrentUser) {
		MJ_BLOCK block = new MJ_BLOCK();
		block.style = Constants.BLOCK_NULL;
		block.first = -1;
		for (int i = 0; i < Constants.HAND_MJ_MAX - 3; i++) {
			if (byMjs[i] == byMj) {
				byMjs[i] = Constants.INVALID_CARD;
				byMjs[i + 1] = Constants.INVALID_CARD;
				byMjs[i + 2] = Constants.INVALID_CARD;
				block.style = Constants.BLOCK_GANG;
				block.first = byMj;
				// 右移4格
				block.OutUserGang = CurrentUser;
				return block;
			}
		}
		return block;
	}

	// 暗杠
	public static BLOCK AnGang(int byMjs[], int GangMj) {
		MJ_BLOCK block = new MJ_BLOCK();
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			if (byMjs[i] == GangMj) {
				byMjs[i] = Constants.INVALID_CARD;
			}
		}
		block.style = Constants.BLOCK_AN_GANG;
		block.first = GangMj;
		return block;
	}

	public static int GetPaiXinAnKe(int tempMj[], HU hu) {
		int total = 0;
		for (int i = 0; i < Constants.MAX_BLOCK_NUM; i++) {
			switch (hu.block[i].style) {
			case Constants.BLOCK_KE:
			case Constants.BLOCK_AN_GANG: {
				total++;
			}
			}
		}
		return total;
	}

	// 七对子
	public static int IsPaiXinQiDuiZi(int byTempMj[]) {
		int OriginalMj[] = new int[Constants.HAND_MJ_MAX];
		Constants.memcpy(OriginalMj, byTempMj, Constants.HAND_MJ_MAX);
		MajHelper.SortCard(OriginalMj, Constants.HAND_MJ_MAX);
		int MjDuiZiCount = 0;
		for (int i = 0; i < Constants.HAND_MJ_MAX - 1; i++) {
			if (MajHelper.IsWTSZ(OriginalMj[i])) {// 不是财神
				if (OriginalMj[i] == OriginalMj[i + 1]) {
					MjDuiZiCount++;
					i++;
				}
			}
		}
		int cntHaoHuaDui = 0;
		for (int i = 0; i < Constants.HAND_MJ_MAX - 3; i++) {
			if (MajHelper.IsWTSZ(OriginalMj[i])) {
				if (OriginalMj[i] == OriginalMj[i + 1] && OriginalMj[i] == OriginalMj[i + 2]
						&& OriginalMj[i] == OriginalMj[i + 3]) {
					cntHaoHuaDui++;
				}
			}
		}
		MajHelper.SortCard(OriginalMj, Constants.HAND_MJ_MAX);
		if (MjDuiZiCount == 7) {
			if (cntHaoHuaDui == 0) {
				return Constants.QI_DUI_ZI;// 七对 2
			}
			if (cntHaoHuaDui == 1) {
				return Constants.HAO_HUA_QI_DUI_ZI;// 豪华七对子 3
			}
			if (cntHaoHuaDui == 2) {
				return Constants.SHUANG_HAO_HUA_QI_DUI_ZI;// 双豪华七对子 4
			}
			if (cntHaoHuaDui == 3) {
				return Constants.SAN_HAO_HUA_QI_DUI_ZI;// 三豪华七对子 5
			}
		}
		return 0;
	}

	// 清一色
	public static boolean IsPaiXinQingYiSe(int tempMj[], HU hu,int pengpai[]) {
		int iWanCount = 0, iSuoCount = 0, iTongCount = 0;
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			if (IsWan(tempMj[i])) {
				iWanCount++;
			} else if (IsTong(tempMj[i])) {
				iTongCount++;
			} else if (IsSuo(tempMj[i])) {
				iSuoCount++;
			} else if (IsZi(tempMj[i])) {
				return false;
			}
		}
		for(int i = 0;i<pengpai.length;i++){
			if(pengpai[i] != 0){
				if (IsWan(pengpai[i])) {
					iWanCount += 3;
				} else if (IsTong(pengpai[i])) {
					iTongCount += 3;
				} else if (IsSuo(pengpai[i])) {
					iSuoCount += 3;
				} else if (IsZi(tempMj[i])) {
					return false;
				}
			}
		}
		if (iWanCount == Constants.HAND_MJ_MAX || iSuoCount == Constants.HAND_MJ_MAX
				|| iTongCount == Constants.HAND_MJ_MAX) {
			return true;
		}
		return false;
	}

	// 混一色
	public static int IsPaiXinHunYiSe(int tempMj[], HU hu, int pengPai[]) {
		int iWanCount = 0, iSuoCount = 0, iTongCount = 0, queCount = 0;
		for (int i = 0; i < Constants.HAND_MJ_MAX; i++) {
			if (IsWan(tempMj[i])) {
				iWanCount++;
			} else if (IsTong(tempMj[i])) {
				iTongCount++;
			} else if (IsSuo(tempMj[i])) {
				iSuoCount++;
			}
		}
		for (int i = 0; i < pengPai.length; i++) {
			if (pengPai[i] != 0) {
				if (IsWan(pengPai[i])) {
					iWanCount++;
				} else if (IsTong(pengPai[i])) {
					iTongCount++;
				} else if (IsSuo(pengPai[i])) {
					iSuoCount++;
				}
			}
		}
		if (iWanCount == 0) {
			queCount++;
		}
		if (iSuoCount == 0) {
			queCount++;
		}
		if (iTongCount == 0) {
			queCount++;
		}
		return queCount;
	}

	// 霍邱麻将添加规则
	private static int MjType_Wan = 1;
	private static int MJType_Tong = 2;
	private static int MjType_Suo = 3;
	private static int MJType_Zi = 4;

	public static int getMjType(int mj) {
		if (mj >= 1 && mj <= 9)
			return MjType_Wan;
		else if (mj >= 11 && mj <= 19)
			return MJType_Tong;
		else if (mj >= 21 && mj <= 29)
			return MjType_Suo;
		else
			return MJType_Zi;
	}

	// 一炮三响
	public static boolean IsPaiXinYiPaoSanXiang(int tempMj[], HU hu) {
		return true;
	}

	public static int IsPaiXinSiGuiYi(int tempMj[], HU hu) {
		int count = 0;
		List<Integer> has3 = new ArrayList<Integer>();
		for (int i = 0; i < Constants.HAND_MJ_MAX - 3; i++) {
			if (tempMj[i] == tempMj[i + 1] && tempMj[i] == tempMj[i + 2]) {
				if (has3.indexOf(tempMj[i]) == -1)
					has3.add(tempMj[i]);
			}
		}
		for (int i = 0; i < has3.size(); i++) {
			int card = has3.get(i);
			int seqvalidcount = 0;
			int same3validcount = 0;
			for (int j = 0; j < Constants.MAX_BLOCK_NUM; j++) {
				BLOCK block = hu.block[j];
				if (block.first == card) {
					switch (block.style) {
					case Constants.BLOCK_SUN: {
						seqvalidcount++;
						break;
					}
					case Constants.BLOCK_KE:
					}
				}
				// 顺子结构不仅第一张，第二张，三张都算的
				// 吃结构第一张第二张一样都算的
				if (block.style == Constants.BLOCK_SUN && (card == block.first + 1 || card == block.first + 2)) {
					seqvalidcount++;
				}
			}
			if (seqvalidcount == 1 && same3validcount == 1) {
				count++;
			}
		}
		return count;
	}

}
